package handler

import (
	"github.com/gin-gonic/gin"
	"github.com/objcoding/wxpay"
	"choujiang/common/models"
	"fmt"
	"net/http"
	"time"
	"choujiang/common/utils"
	"choujiang/common/consts"
	"strconv"
	"choujiang/box_server/service"
)

const (
	WECHAT_ACCOUNT_APPID = "wx7c7e5b614cf22016"
	WECHAT_MCHID         = "1490679542"
	WECHAT_API_KEY       = "leyou2018leyou2018leyou2018leyou"
	WECHAT_CERT_PATH     = "/data/wwwroot/leyou_admin/cert/apiclient_cert.pem"
)

/**
 @description 商品下单接口
 @return mixed
 @author guxiang
 @version v1 2018-11-24
 */
//func AddPayment(c *gin.Context) {
//	form := c.Request.Form
//	gameId := form.Get("gameId")
//	uniqueId := form.Get("uniqueId")
//	openId := form.Get("openId")
//	user := model.GetUserByUniqueId(uniqueId)
//	if user == nil {
//		utils.Error(consts.ErrUserNotFound, c)
//		return
//	}
//	game := model.GetGameByGameId(gameId)
//	if game == nil {
//		utils.Error(consts.ErrGoodsNotFound, c)
//		return
//	}
//	// 创建支付账户
//	account := wxpay.NewAccount(WECHAT_ACCOUNT_APPID, WECHAT_MCHID, WECHAT_API_KEY, false)
//	// 新建微信支付客户端
//	client := wxpay.NewClient(account)
//	// 设置证书
//	account.SetCertData(WECHAT_CERT_PATH)
//	// 设置支付账户
//	client.SetAccount(account)
//	// 设置http请求超时时间
//	client.SetHttpConnectTimeoutMs(2000)
//	// 设置http读取信息流超时时间
//	client.SetHttpReadTimeoutMs(1000)
//	// 更改签名类型
//	client.SetSignType("MD5")
//	// 统一下单
//	time_stamp := strconv.FormatInt(time.Now().Unix(), 10)
//	order_sn := utils.GenOrderSn(uniqueId, time_stamp)
//	params := make(wxpay.Params)
//	params.SetString("body", "payment").
//		SetString("out_trade_no", order_sn).
//		SetInt64("total_fee", int64(game.Price)).
//		SetString("spbill_create_ip", "140.143.182.245").
//		SetString("notify_url", "https://box-dev.leyougame.cc/api/v1/payment/payback").
//		SetString("trade_type", "JSAPI").
//		SetString("openid", openId)
//	p, err := client.UnifiedOrder(params)
//	signParam := map[string]string{
//		"appId": p["appid"],
//		"noneStr": p["nonce_str"],
//		"package": "prepay_id="+p["prepay_id"],
//		"signType": "MD5",
//		"timeStamp": time_stamp,
//	}
//	paySign := utils.PaymentSign(WECHAT_API_KEY, signParam)
//	if err != nil {
//		fmt.Printf("AddPayment err %s", err)
//	} else {
//		//保留订单信息
//		newOrder := &model.Orders{
//			OrderSn:   order_sn,
//			GoodsId:   game.Id,
//			GoodsNum:  1,
//			UserId:    user.Id,
//			Cost:      1,
//			OrderType: 2,
//		}
//		if _, err := newOrder.Insert(); err != nil {
//			fmt.Printf("err %+v\n", err)
//		}
//	}
//	p["time_stamp"] = time_stamp
//	p["pay_sign"] = paySign
//	utils.JSON(p, c)
//}

/**
 @description 商品下单接口
 @return mixed
 @author guxiang
 @version v1 2018-11-24
 */
func AddPayment(c *gin.Context) {
	form := c.Request.Form
	gameId := form.Get("gameId")
	uniqueId := form.Get("uniqueId")
	openId := form.Get("openId")
	user := model.GetUserByUniqueId(uniqueId)
	if user == nil {
		utils.Error(consts.ErrUserNotFound, c)
		return
	}
	game := model.GetGameByGameId(gameId)
	if game == nil {
		utils.Error(consts.ErrGoodsNotFound, c)
		return
	}
	if game.Balance <= 0 {
		utils.Error(consts.ErrGameBalanceFail, c)
		return
	}
	time_stamp := strconv.FormatInt(time.Now().Unix(), 10)
	orderSn := utils.GenOrderSn(uniqueId, time_stamp)
	p, err := service.CreateGameOrder(orderSn, openId, game.Balance)
	if err != nil {
		fmt.Printf("err %+v\n", err)
		utils.Error(consts.ErrUnifiedOrderFail, c)
		return
	}
	//保留订单信息
	newOrder := &model.Orders{
		OrderSn:   orderSn,
		GoodsId:   game.Id,
		GoodsNum:  1,
		UserId:    user.Id,
		Cost:      game.Balance,
		OrderType: 2,
		Channel:   user.FromChannel,
	}
	if _, err := newOrder.Insert(); err != nil {
		fmt.Printf("err %+v\n", err)
	}
	utils.JSON(p, c)
}

/**
 @description 微信支付异步结果通知
 @return SUCCESS | FAIL
 @author guxiang
 @version v1 2018-11-27
 */
func WechatPayBack(c *gin.Context) {
	fmt.Println("------------------WechatPayBack in")
	b, _ := c.GetRawData()
	xmlStr := string(b)
	// 创建支付账户
	account := wxpay.NewAccount("wxd4a9dc7a723dbee9", "1490679542", "leyou2018leyou2018leyou2018leyou", false)
	// 新建微信支付客户端
	client := wxpay.NewClient(account)
	var returnCode string
	params := wxpay.XmlToMap(xmlStr)
	c.Header("Content-Type", "application/xml; charset=utf-8")
	if params.ContainsKey("return_code") {
		returnCode = params.GetString("return_code")
	} else {
		reXml := setResponseXml("FAIL", "no return_code in XML")
		c.String(http.StatusOK, reXml)
		return
	}
	if returnCode == "FAIL" {
		reXml := setResponseXml("SUCCESS", "")
		c.String(http.StatusOK, reXml)
		return
	} else if returnCode == "SUCCESS" {
		if client.ValidSign(params) {
			if params.ContainsKey("out_trade_no") { //包含商户订单
				go func() {
					out_trade_no := params.GetString("out_trade_no")
					completeOrder(out_trade_no)
				}()
			}
			reXml := setResponseXml("SUCCESS", "")
			c.String(http.StatusOK, reXml)
			return
		} else {
			reXml := setResponseXml("FAIL", "invalid sign value in XML")
			c.String(http.StatusOK, reXml)
			return
		}
	} else {
		reXml := setResponseXml("FAIL", "return_code value is invalid in XML")
		c.String(http.StatusOK, reXml)
		return
	}
}

/**
 @description 封装xml返回值
 @return string
 @author guxiang
 @version v1 2018-11-27
 */
func setResponseXml(return_code, return_msg string) string {
	var params = make(wxpay.Params)
	params.SetString("return_code", return_code)
	params.SetString("return_msg", return_msg)
	reXml := wxpay.MapToXml(params)
	return reXml
}

/**
 @description 完成订单，改变订单状态
 @return
 @author guxiang
 @version v1 2018-11-27
 */
func completeOrder(out_trade_no string) {
	order := model.GetOrderByOrderSn(out_trade_no)
	if order == nil {
		fmt.Printf("completeOrder err order is nil")
		return
	}
	order.OrderStatus = 1
	order.PayAt = time.Now().Unix()
	_, err := order.Update()
	if err != nil {
		fmt.Printf("completeOrder err order update fail")
		return
	}
	game := model.GetGameById(order.GoodsId)
	if game != nil {
		game.AccumPromote = game.AccumPromote + 1
		_, err := game.Update()
		if err != nil {
			fmt.Printf("completeOrder err game update fail")
			return
		}
		user := model.GetUserByUid(order.UserId)
		if user != nil {
			uGame := &model.UserGames{
				UserId: order.UserId,
				GameId: game.Id,
				Status: 1,
			}
			if _, err := uGame.Insert(); err != nil {
				fmt.Printf("err %+v\n", err)
			}
		}
	}
	return
}
